<?php
/***
* @version $Id: mysqli.php 336 2007-01-23 08:12:56Z flexiondotorg $
* @copyright (c) 2006 - 2007 Flexion.Org
*            (c) 2004 - 2005  Nev (invisible@hidden-city.net)
*            (c) 2004 - 2005 Project Minerva
*            (c) 2001 - 2006 phpBB Group
* @license   http://opensource.org/licenses/gpl-license.php GNU Public License
***/

if(!defined('SQL_LAYER'))
{

define('SQL_LAYER','mysqli');

class sql_db
{
    # These are private vars, nobody else cares about them then us...
    # Not completely true: ../includes/db.php uses $db_connect_id but that's about it :]
    var $db_connect_id;
    var $query_result;
    var $row = array();
    var $rowset = array();        # is this anything different than $row ?
    var $num_queries = 0;        # not used for anything usefull ?
    var $in_transaction = 0;

    //
    // Constructor
    //
    # connect to the db server and select working db
    # returns sql connection resource
	# MySQLi doesn't have a persistent connection option and selecting the db is not required since we do that with the 4th parameter in mysqli_connect.
    function sql_db($sqlserver, $sqluser, $sqlpassword, $database, $persistency = false )
    {
		$this->persistency = $persistency;
        $this->user = $sqluser;
        $this->password = $sqlpassword;
        $this->server = $sqlserver;
        $this->dbname = $database;

        $this->db_connect_id = mysqli_connect($this->server, $this->user, $this->password, $this->dbname );

        if( $this->db_connect_id )
        {
            return $this->db_connect_id;
        }
        else
        {
            return false;
        }
    }

    //
    // Other base methods
    //
    # close the db connection
    function sql_close()
    {
        if( $this->db_connect_id )
        {
            //
            // Commit any remaining transactions
            //
            if( $this->in_transaction )
            {
                mysqli_query( $this->db_connect_id, "COMMIT" );
            }

            return mysqli_close($this->db_connect_id);
        }
        else
        {
            return false;
        }
    }

    //
    // Base query method
    //
    # $transaction = FALSE as function parameter is bogus, since it is never used ?
    #
    # Put result resource of a query in $this->query_result
    # Reset $this->row and $this->rowset
    #
    # Returns query resource
    function sql_query($query = "", $transaction = FALSE)
    {
        //
        // Remove any pre-existing queries
        //
        unset($this->query_result);

        if( $query != "" )
        {
            $this->num_queries++;
            if( $transaction == BEGIN_TRANSACTION && !$this->in_transaction )
            {
                $result = mysqli_query( $this->db_connect_id, "BEGIN" );
                if(!$result)
                {
                    return false;
                }
                $this->in_transaction = TRUE;
            }

            $this->query_result = mysqli_query( $this->db_connect_id, $query );
        }
        else
        {
            if( $transaction == END_TRANSACTION && $this->in_transaction )
            {
                $result = mysqli_query( $this->db_connect_id, "COMMIT" );
            }
        }

        if( $this->query_result )
        {
            unset($this->row[$this->query_result]);
            unset($this->rowset[$this->query_result]);

            if( $transaction == END_TRANSACTION && $this->in_transaction )
            {
                $this->in_transaction = FALSE;

                if ( !mysqli_query( $this->db_connect_id, "COMMIT" ) )
                {
                    mysqli_query( $this->db_connect_id, "ROLLBACK" );
                    return false;
                }
            }

            return $this->query_result;
        }
        else
        {
            if( $this->in_transaction )
            {
                mysqli_query( $this->db_connect_id, "ROLLBACK" );
                $this->in_transaction = FALSE;
            }
            return false;
        }
    }

    //
    // Other query methods
    //
    # how many rows do we have in a $query_id result resource
    # returns an int
    function sql_numrows($query_id = 0)
    {
        if( !$query_id )
        {
            $query_id = $this->query_result;
        }

        return ( $query_id ) ? mysqli_num_rows($query_id) : false;
    }

    # how many rows were affected
    # returns an int
    function sql_affectedrows()
    {
        return ( $this->db_connect_id ) ? mysqli_affected_rows($this->db_connect_id) : false;
    }

    # how many fields do we have in query resource
    # returns an int
    function sql_numfields($query_id = 0)
    {
        if( !$query_id )
        {
            $query_id = $this->query_result;
        }

        return ( $query_id ) ? mysqli_num_fields($query_id) : false;
    }

    # what is the filedname at $offset
    # returns a string
    function sql_fieldname($offset, $query_id = 0)
    {
        if( !$query_id )
        {
            $query_id = $this->query_result;
        }

        if( $query_id )
        {
            $field_name = mysqli_fetch_field_direct($query_id, $offset);
            return $field_name->name;
        }
        else
        {
            return false;
        }
    }

    # what is type of data at field $offset
    #
    # ok this is bogus function. It is called only from
    # /admin/admin_db_utilities.php, and only if the db if pgsql
    # mysql db's use this function at all, everything is in
    # functions get_table_def_mysql and get_table_content_mysql
    # in /admin/admin_db_utilities.php
    function sql_fieldtype($offset, $query_id = 0)
    {
        if( !$query_id )
        {
            $query_id = $this->query_result;
        }

        if( $query_id )
        {
            $field_name = mysqli_fetch_field_direct($query_id, $offset);
            return $field_name->type;
        }
        else
        {
            return false;
        }
    }

    # fetch the rows from $query_id resource and put it in
    # $this->row
    # return type is associative array
    function sql_fetchrow($query_id = 0)
    {
        if( !$query_id )
        {
            $query_id = $this->query_result;
        }

        if( $query_id )
        {
            $this->row[$query_id] = mysqli_fetch_array($query_id, MYSQLI_ASSOC );
            return $this->row[$query_id];
        }
        else
        {
            return false;
        }
    }

    # i don't really see how this is much different than
    # previous function sql_fetchrow
    # Unsets $this->row, $this->rowset
    # return type is associative array
    function sql_fetchrowset($query_id = 0)
    {
        if( !$query_id )
        {
            $query_id = $this->query_result;
        }

        if( $query_id )
        {
            unset($this->rowset[$query_id]);
            unset($this->row[$query_id]);

            while($this->rowset[$query_id] = mysqli_fetch_array($query_id, MYSQLI_ASSOC))
            {
                $result[] = $this->rowset[$query_id];
            }

            return $result;
        }
        else
        {
            return false;
        }
    }

    # fetch particular fields in a particular row
    # return type depends on the fetched field type
    function sql_fetchfield($field, $rownum = -1, $query_id = 0)
    {
        if( !$query_id )
        {
            $query_id = $this->query_result;
        }

        if( $query_id )
        {
            if( $rownum > -1 )
            {
                # this is a bit ugly since we don't have mysql_result in mysqli ext
                if( $rownum >= $this->sql_numrows( $query_id ) )
                {
                    return false;
                }
                else
                {
                    $temp_row_num = 0;
                    while ($row = mysqli_fetch_row( $query_id ) ) {
                        if( $rownum == $temp_row_num )
                            return $row[$field];
                        $temp_row_num++;
                    }
                }
            }
            else
            {
                if( empty($this->row[$query_id]) && empty($this->rowset[$query_id]) )
                {
                    if( $this->sql_fetchrow() )
                    {
                        $result = $this->row[$query_id][$field];
                    }
                }
                else
                {
                    if( $this->rowset[$query_id] )
                    {
                        $result = $this->rowset[$query_id][$field];
                    }
                    else if( $this->row[$query_id] )
                    {
                        $result = $this->row[$query_id][$field];
                    }
                }
            }

            return $result;
        }
        else
        {
            return false;
        }
    }

    # set internal pointer in $query_id to a particular row ?
    function sql_rowseek($rownum, $query_id = 0)
    {
        if( !$query_id )
        {
            $query_id = $this->query_result;
        }

        return ( $query_id ) ? mysqli_data_seek($query_id, $rownum) : false;
    }

    # return the id of newly inserted item
    function sql_nextid()
    {
        return ( $this->db_connect_id ) ? mysqli_insert_id($this->db_connect_id) : false;
    }

    # free the results, and clean $this->row, $this->rowset
    function sql_freeresult($query_id = 0)
    {
        if( !$query_id )
        {
            $query_id = $this->query_result;
        }

        if ( $query_id )
        {
            unset($this->row[$query_id]);
            unset($this->rowset[$query_id]);

            mysqli_free_result($query_id);

            return true;
        }
        else
        {
            return false;
        }
    }

    # return mysqli error message and code
    function sql_error()
    {
        $result['message'] = mysqli_error($this->db_connect_id);
        $result['code'] = mysqli_errno($this->db_connect_id);

        return $result;
    }
} // class sql_db

} // if ... define

?>